package com.woniu.zsd.user.controller;


import com.woniu.dto.LogUserDto;
import com.woniu.form.LoginByPhoneForm;
import com.woniu.form.LoginByUsernameForm;
import com.woniu.form.UserRegisterForm;
import com.woniu.zsd.commons.core.model.Result;
import com.woniu.zsd.permission.Permission.Permission;
import com.woniu.zsd.user.service.IUserLogService;
import com.woniu.zsd.user.service.IUserService;
import com.woniu.commons.util.JwtUtil;
import com.woniu.commons.util.RedisKey;
import com.woniu.zsd.user.utils.UserTokenUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2025-03-27
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户业务")
public class UserController {
    @Autowired
    private IUserService userService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IUserLogService userLogService;

    @Autowired
    private UserTokenUtil tokenUtil;

    @Autowired
    private JwtUtil jwtUtil;

    @GetMapping("/sendRegisterCode")
    @ApiOperation(value = "手机注册获取验证码")
    public Result sendRegisterCode(@RequestParam String phone){
        userService.sendRegisterCode(phone);
        return Result.getResult(Boolean.class).setData(true).setMsg("验证码发送成功");
    }
    @GetMapping("/sendLoginCode")
    @ApiOperation(value = "获取验证码")
    public Result sendLoginCode(@RequestParam String phone){
        userService.sendLoginCode(phone);
        return Result.getResult(Boolean.class).setData(true).setMsg("验证码发送成功");
    }
    @PostMapping("/register")
    @ApiOperation(value = "用户注册")
    public Result register(@ApiParam(name = "userRegisterForm", value = "用户注册表单")@RequestBody UserRegisterForm userRegisterForm) throws Exception {
        userService.register(userRegisterForm);
        return Result.getResult(Boolean.class).setData(true).setMsg("注册成功");
    }

    @PostMapping("/loginByPhone")
    @ApiOperation(value = "手机号+验证码登录")
    public Result loginByPhone(@ApiParam(name = "lbpf", value = "手机号登录表单")@RequestBody LoginByPhoneForm lbpf, HttpServletRequest request,HttpServletResponse response) throws Exception {
        LogUserDto dto = userService.loginByPhoneAndCode(lbpf);

        // 生成双token
        HashMap<String, Object> body = new HashMap<>();
        body.put("id", dto.getId());
        String accessToken = jwtUtil.createToken(body, 30);
        String refreshToken = jwtUtil.createToken(body, 60 * 24);
        response.setHeader("Access-Control-Expose-Headers","token");
        // 将refreshToken保存到redis中
        stringRedisTemplate.opsForValue().set(RedisKey.USER_REFRESH_TOKEN_KEY(accessToken), refreshToken, 60 * 24, TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().set(RedisKey.USER_ACCESS_TOKEN_KEY(String.valueOf(dto.getId())), accessToken, 30, TimeUnit.MINUTES);

        // 响应accessToken到前端
        response.setHeader("token", accessToken);
        userLogService.addLog(lbpf.getLoginAddress(), String.valueOf(dto.getId()),request);
        return Result.getResult().setMsg("登录成功");
    }

    @PostMapping("/loginByUsername")
    @ApiOperation(value = "用户名+密码登录")
    public Result loginByUsername(@ApiParam (name = "lbuf", value = "用户名登录表单")@RequestBody LoginByUsernameForm lbuf, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LogUserDto dto = userService.loginByUsernameAndPassword(lbuf);

        // 生成双token
        HashMap<String, Object> body = new HashMap<>();
        body.put("id", dto.getId());
        String accessToken = jwtUtil.createToken(body, 30);
        String refreshToken = jwtUtil.createToken(body, 60 * 24);
        response.setHeader("Access-Control-Expose-Headers","token");
        // 将refreshToken保存到redis中
        stringRedisTemplate.opsForValue().set(RedisKey.USER_REFRESH_TOKEN_KEY(accessToken), refreshToken, 60 * 24, TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().set(RedisKey.USER_ACCESS_TOKEN_KEY(String.valueOf(dto.getId())), accessToken, 30, TimeUnit.MINUTES);

        // 响应accessToken到前端
        response.setHeader("token", accessToken);
        userLogService.addLog(lbuf.getLoginAddress(), String.valueOf(dto.getId()),request);
        return Result.getResult().setMsg("登录成功");
    }
    @GetMapping("/loginOut")
    @ApiOperation(value = "退出登录")
    public Result loginOut(@ApiParam(name = "token", value = "token")@RequestHeader String token, HttpServletRequest request){
        Integer id = tokenUtil.getUserId(token);
        stringRedisTemplate.delete(RedisKey.USER_ACCESS_TOKEN_KEY(String.valueOf(id)));
        stringRedisTemplate.delete(RedisKey.USER_REFRESH_TOKEN_KEY(token));
        return Result.getResult(Boolean.class).setData(true).setMsg("退出成功");
    }

    @PutMapping("/banUser")
    @ApiOperation(value = "封号/解封")
    @Permission("banUser")
    public Result banUser(@ApiParam(name = "id", value = "用户id")@RequestParam String id, @RequestHeader String token){
        userService.banUser(id);
        return Result.getResult(Boolean.class).setData(true).setMsg("操作成功");
    }
}
